<script
  lang="ts"
  setup
  generic="
    T extends {
      id: number
    }
  "
>
import { Button, Input, Popconfirm, Table, message, Modal, Form, Select } from 'ant-design-vue'
import dayjs from 'dayjs'
import type { AfterFetchContext } from '@vueuse/core'
import type { ColumnsType } from 'ant-design-vue/es/table'
import type { IModule } from '~/types/apis/module'
import type { IBasic, IBasicWithPage } from '~/types/apis/basic'
import { reactive } from 'vue'
import { useGlobalConfigStore } from '~/stores/global-config.store'

const props = withDefaults(
    defineProps<{
        baseName: string
        localizedName: string
        columns: ColumnsType<any>
        notFetchDefaultData?: boolean
        loadingWithAnotherTableDataSource?: boolean
        anotherTableDataSource?: T[]
        showEditor?: boolean
    }>(),
    {
        showEditor: false,
        notFetchDefaultData: false,
        loadingWithAnotherTableDataSource: false,
        anotherTableDataSource: () => [],
    },
)

const globalConfig = useGlobalConfigStore()


// 复选框选中的选项
const state = reactive<{
    selectedRowKeys: Key[];
}>({
    selectedRowKeys: [], // Check here to configure the default column
});

const emits = defineEmits<{
    (e: 'fetchDataSource'): void
}>()

let { baseName, columns, notFetchDefaultData } = toRefs(props)
const globalConfigStore = useGlobalConfigStore()
const { selectedModuleId } = storeToRefs(useTemporaryStore())
const { setModules, setSelectedModuleId, setEditState } = useTemporaryStore()

let moduleId = selectedModuleId.value
const { modules } = storeToRefs(useTemporaryStore())

const listUrl = computed(() => {
    if (baseName.value === 'before_case') {
        return `/engine-service/api/v1/${baseName.value}/list`
    } else {
        return `/engine-service/api/v1/${baseName.value}_module/list`
    }
})

const { execute: fetchApiModules, isFetching: loadingWithGetApiModules } =
    useCustomFetch<IModule[]>(
        listUrl,
        {
            immediate: false,
            async afterFetch(ctx: AfterFetchContext<IBasic<IModule[]>>) {
                searchStatus.value = false;
                if (baseName.value === 'before_case') {
                    if (ctx.data && ctx.data.data.length > 0) {
                        tableDataSource.value = ctx.data.data
                    }
                } else {
                    if (ctx.data && ctx.data.data.length > 0) {
                        const moduleId = ctx.data.data[0].id
                        if (selectedModuleId.value === -1 || !ctx.data.data.some((item) => item.id === selectedModuleId.value)) {
                            setSelectedModuleId(moduleId)
                        }
                        setModules(ctx.data.data)
                    } else {
                        console.info(`未查到${baseName.value}_module数据`)
                        setSelectedModuleId(-1)
                        setModules([])
                        tableDataSource.value = []
                    }

                    !notFetchDefaultData.value
                        ? await fetchGetTableDataSource()
                        : emits('fetchDataSource')
                }
                return ctx
            },
        },
    )

const fetchFindTableDataSourceUrl = computed(() => {
    if (baseName.value === 'before_case') {
        return handleParams(`/engine-service/api/v1/${baseName.value}/find`, {
            id: selectedModuleId.value,
        })
    } else {
        return handleParams(`/engine-service/api/v1/${baseName.value}_module/find`, {
            moduleId: selectedModuleId.value,
        })
    }

})
const {
    execute: fetchGetTableDataSource,
    data: tableDataSource,
    isFetching: loadingWithGetTableDataSource,
} = useCustomFetch<T[]>(fetchFindTableDataSourceUrl, {
    immediate: false,
    initialData: [],
    afterFetch(ctx: AfterFetchContext<IBasic<IModule<T>>>) {
        if (ctx.data && ctx.data.code === 0) {
            // 每次切换模块，查询完case都要清空复选框集合
            state.selectedRowKeys = [];
            searchStatus.value = false;
            return {
                data: ctx.data.data.list,
                response: ctx.response,
            }
        }
        return {
            data: [],
            response: ctx.response,
        }
    },
})

// const tablePagination = reactive({
//   pageNum: 0,
//   pageSize: 10,
//   moduleId: -1,
// })
// const tableDataSourceUrl = computed(() => {
//   return handleParams(
//     `/engine-service/api/v1/${baseName.value}/find`,
//     tablePagination,
//   )
// })
// const {
//   data: tableDataSource,
//   execute: fetchGetTableDataSource,
//   isFetching: loadingWithGetTableDataSource,
// } = useCustomFetch<T[]>(tableDataSourceUrl, {
//   immediate: false,
//   initialData: [],
//   afterFetch(ctx: AfterFetchContext<IBasicWithPage<T>>) {
//     if (ctx.data && ctx.data.data.current_data.length > 0) {
//       return {
//         data: ctx.data.data.current_data,
//         response: ctx.response,
//       }
//     }
//     return {
//       data: [],
//       response: ctx.response,
//     }
//   },
// })

const { post: fetchDeleteApi } = useCustomFetch<T[]>(
    `/engine-service/api/v1/${baseName.value}/del`,
    {
        immediate: false,
        afterFetch(ctx: AfterFetchContext<IBasic<any>>) {
            if (ctx.data && ctx.data.code === 0) {
                message.success(ctx.data.msg ?? '删除成功')
            }
            return ctx
        },
    },
)

const route = useRoute()
const router = useRouter()

function pushNewOrEdit(isEdit?: boolean, record?: T) {
    globalConfig.setControlStepState(isEdit ? 'edit' : 'new')
    if (baseName.value !== 'before_case') {
        // 先判断是否存在moduleId
        if (selectedModuleId.value == -1) {
            message.error("请先创建一个模块，点击右上角'+'号, 双击生成的模块可以更改名字")
            return;
        }
    }
    router.push(
        `${route.fullPath}/new-or-edit${isEdit ? '?is-edit=true' : ''}${record ? `&id=${record.id}` : ''}`,
    )
}

function handleEdit(record: T) {
    setEditState(record)
    pushNewOrEdit(true, record)
}

async function handleDelete(id: number) {
    await fetchDeleteApi({ id }).execute()
    !notFetchDefaultData.value
        ? searchStatus ? fetchGetSearchDataSource() : fetchGetTableDataSource()
        : emits('fetchDataSource')
}





watch(selectedModuleId, () => {
    !notFetchDefaultData.value
        ? fetchGetTableDataSource()
        : emits('fetchDataSource')
})

watchImmediate(
    () => globalConfigStore.config.projectId,
    async () => {
        console.info("监听模块")
        await fetchApiModules()
    },
)


// ---------------------------------↓↓↓复制case相关代码↓↓↓--------------------


const [copyModalVisible, toggleCopyModalVisible] = useToggle(false)
const fetchGetApiCaseUrl = computed(() =>
    `/engine-service/api/v1/${baseName.value}/find?`,
)
const { isFetching, execute: fetchGetApiCase } = useCustomFetch(
    fetchGetApiCaseUrl,
    {
        immediate: false,
        afterFetch(ctx: AfterFetchContext<IBasic<any>>) {
            if (ctx.data && ctx.data.code === 0) {
                formModel.value = {
                    ...formModel.value,
                    ...ctx.data.data,
                    stepList: ctx.data.data.list,
                }
                formModel.value.stepList = formModel.value.stepList.map((item) => ({
                    ...defaultWithStepItem.value,
                    ...item,
                    caseId: formModel.value.id,
                }))
            }
            return ctx
        },
    },
)


// 复选框变化时触发
const onSelectChange = (selectedRowKeys: Key[]) => {
    console.log('selectedRowKeys changed: ', selectedRowKeys);
    state.selectedRowKeys = selectedRowKeys;
};




// Model弹出后点击ok按钮
function copyCase() {
    console.log('selected: ', state.selectedRowKeys);
    if (state.selectedRowKeys.length === 0) {
        message.error("请选择用例，再进行复制")
    } else {
        toggleCopyModalVisible(true)
    }
}

async function handleCurrentModuleCopy(id: number) {
    // 调用复制接口, 固定复制到当前module之下， 参数在这里传
    const copyCase = [id]
    await handlerFetchCopyCase({ idList: copyCase, moduleId: selectedModuleId.value }).execute()
}



const { post: handlerFetchCopyCase } = useCustomFetch(
    `/engine-service/api/v1/${baseName.value}/copy`,
    {
        immediate: false,
        async afterFetch(ctx: AfterFetchContext<IBasic<any>>) {
            if (ctx.data && ctx.data.code === 0) {

                message.success(ctx.data.msg ?? '复制成功')
                // 重新刷一遍数据
                searchStatus ? await fetchGetSearchDataSource() : await fetchApiModules()
                toggleCopyModalVisible(false)
            }
            return ctx
        },
    },
)

const handleCopyCase = async () => {
    // 调用复制接口， 参数在这里传
    await handlerFetchCopyCase({ idList: state.selectedRowKeys, moduleId: moduleId }).execute()
}
// 下拉列表更换值
const handleChange = (value: number) => {
    console.info("要复制到的目标moduleId: " + JSON.stringify(value))
    // 这里moduleId要等与所选的module，因为这个mouduleId是作为复制case的条件
    moduleId = value
};

// --------------------------------------↑↑↑复制case相关代码↑↑↑-------------------


const searchValue = ref('')
const searchStatus = ref(false)

// 搜索
const fetchFindSearchDataSourceUrl = computed(() => {
    return handleParams(`/engine-service/api/v1/${baseName.value}/list`, {
        projectId: globalConfigStore.config.projectId,
        moduleId: selectedModuleId.value,
        name: searchValue.value
    })
})
const {
    execute: fetchGetSearchDataSource,
    data: searchDataSource,
    isFetching: loadingWithGetSearchDataSource,
} = useCustomFetch<T[]>(fetchFindSearchDataSourceUrl, {
    immediate: false,
    initialData: [],
    afterFetch(ctx: AfterFetchContext<IBasic<IModule<T>>>) {
        if (ctx.data && ctx.data.code === 0) {
            // 每次切换模块，查询完case都要清空复选框集合
            state.selectedRowKeys = [];
            searchStatus.value = true;
            console.log("搜索数据-->", ctx.data.data)
            return {
                data: ctx.data.data,
                response: ctx.response,
            }
        }
        return {
            data: [],
            response: ctx.response,
        }
    },
})

const resetSearch = () => {
    searchValue.value = "";
    searchStatus.value = false;
    if (baseName.value === 'before_case') {
        !notFetchDefaultData.value
            ? fetchApiModules()
            : emits('fetchDataSource')
    } else {
        !notFetchDefaultData.value
            ? fetchGetTableDataSource()
            : emits('fetchDataSource')
    }
}

</script>

<template>
    <div :class="[
        loadingWithGetApiModules &&
        'opacity-50 pointer-events-none cursor-not-allowed',
    ]">
        <ModuleManager v-if="baseName !== 'before_case'" :base-name="baseName" :title="localizedName"
            :selected-module-id="selectedModuleId ?? -1" @refresh-modules="fetchApiModules()" />
        <div mt>
            <div mb flex items-center>
                <div space-x-2 style="margin-right: 20px">
                    <Button type="primary" @click="pushNewOrEdit()">新增{{ localizedName }}</Button>
                </div>
                <div space-x-2 style="margin-right: 20px">
                    <Button type="primary" @click="copyCase()">复制用例</Button>
                </div>

                <div flex space-x-2 style="margin-left: 40px">
                    <Input placeholder="请输入名称" v-model:value="searchValue" />
                    <Button type="primary" @click="fetchGetSearchDataSource">搜索</Button>
                    <Button type="dashed" @click="resetSearch">重置</Button>
                </div>
            </div>

            <Table :row-selection="{ selectedRowKeys: state.selectedRowKeys, onChange: onSelectChange }" :columns="columns"
                :loading="!notFetchDefaultData ? loadingWithGetTableDataSource! : loadingWithAnotherTableDataSource"
                :data-source="!notFetchDefaultData ? searchStatus ? searchDataSource : tableDataSource! : anotherTableDataSource"
                :row-key="record => record.id" :pagination="false">
                <template #bodyCell="{ record, column, index, text, value }">
                    <slot name="bodyCell" :record="record" :column="column" :index="index" :text="text" :value="value" />

                    <template v-if="['gmtCreate', 'gmtModified'].includes(column.key!.toString())">
                        {{
                            dayjs(record[column.key as string]).format(
                                'YYYY-MM-DD - HH:mm:ss',
                            )
                        }}
                    </template>

                    <template v-if="column.key === 'operation'">
                        <div>
                            <Button v-if="!showEditor" type="link" @click="handleEdit(record as T)"><span
                                    text-green>编辑</span></Button>
                            <slot name="operation" :record="record as T" :column="column" :index="index" :text="text"
                                :value="value" />
                            <Popconfirm title="确认是否删除？" @confirm="handleDelete((record as T).id)">
                                <Button type="link"><span text-red>删除</span></Button>
                            </Popconfirm>

                            <slot name="operation2" :record="record as T" :column="column" :index="index" :text="text"
                                :value="value" />
                            <Popconfirm title="确认是否复制该case到当前module中？" @confirm="handleCurrentModuleCopy((record as T).id)">
                                <Button type="link">复制</Button>
                            </Popconfirm>
                        </div>

                    </template>
                </template>
            </Table>


            <!-- 复制用例 -->
            <Modal v-model:open="copyModalVisible" title="复制用例" @ok="handleCopyCase">
                <div style="">
                    <Form layout="inline" :label-col="{ span: 4 }" :wrapper-col="{ span: 16 }" autocomplete="off" style="
            display: flex;
            height: 150px;
            flex-direction: column;
            justify-content: space-around;
          ">

                        <Form.Item label="模块ID：">

                            <Select :default-value="moduleId" @change="handleChange">
                                <Select.Option v-for="{ id, name } in modules" :key="id" :value="id">
                                    <Tooltip>{{ name }}</Tooltip>
                                </Select.Option>
                            </Select>


                        </Form.Item>

                    </Form>
                </div>
            </Modal>
        </div>
    </div>
</template>
